import time
from paddleocr import PaddleOCR
import cv2
from typing import Literal, Tuple,List, Union
import os
import time
import math
import numpy as np
from .utils import write_image
from .appium_driver import driver

ocr = PaddleOCR(lang="ch", show_log=False)
class OcrLine:
    position:Tuple[Tuple[int,int],Tuple[int,int],Tuple[int,int],Tuple[int,int]]
    string:str
    def __init__(self,position,string) -> None:
        self.position = position
        self.string = string
print('ocr初始化完毕')
def getArea(img,area):
    shape = img.shape
    startX = 0
    startY = 0
    endX = shape[1]
    endY = shape[0]
    if area == 'top':
        endY = math.floor(shape[0]/2)
    if area == 'bottom':
        startY = math.floor(shape[0]/2)
    if area == 'center':
        startY = math.floor(shape[0]/2)
        startY = math.floor(shape[0]/2)
    return (startX,startY),img[startY:endY, startX:endX]
def getProcessedImg(img):
    gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _, binary_thresh = cv2.threshold(gray_image, 180, 255, cv2.THRESH_BINARY)
    return binary_thresh


def getFilteredResult(img)->List[OcrLine]:
    response = []
    listToBeReplace = [('－','-'),('一','-'),('?','')]
    result = ocr.ocr(img, cls=False)
        
    for res in result:
        if res is None:
            continue
        for line in res:
            string = line[1][0]
            for item in listToBeReplace:
                string = string.replace(item[0],item[1])
            response.append(OcrLine(line[0],string))
    return response
loopTime = 0
def findString(target: Union[str, List[str]],
                like = False, loop = False,
                tap=False, offset=(0, 0), timeout=0.5,
                tapDirection:Literal["left","top","right","bottom","center"] = None,
                swipeDirection:Literal["left","top","right","bottom","center"] = None,
                area:Literal["top","bottom"] = None,
                img = None):
    global loopTime
    if loopTime == 0:
        print(f'findString {target}')
        loopTime += 1
    if img is None:
        img = driver.getScreenshotForCv2()
    areaOffset = (0,0)
    if area:
        areaOffset,img = getArea(img,area)
    center = [img.shape[1]//2,img.shape[0]//2]
    result = getFilteredResult(img)
    # cv2.imshow('1',img)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()

    if isinstance(target,str):
        stringList = [target]
    if isinstance(target,list):
        stringList = target
    successLine = None
    for line in result:
        for string in stringList:
            if line.string == string or (like and string in line.string):
                if not successLine:
                    successLine = line
                elif string == successLine.string  or (like and string in successLine.string):
                    position = successLine.position
                    pixelX = (position[0][0]+position[1][0])/2
                    pixelY = (position[0][1]+position[3][1])/2
                    oldDistance = math.sqrt((pixelX - center[0])**2+(pixelY - center[1])**2)
                    position = line.position
                    pixelX = (position[0][0]+position[1][0])/2
                    pixelY = (position[0][1]+position[3][1])/2
                    newDistance = math.sqrt((pixelX - center[0])**2+(pixelY - center[1])**2)
                    if newDistance < oldDistance:
                        successLine = line
    if successLine is not None:
        position = successLine.position
        pixelX = (position[0][0]+position[1][0])/2+areaOffset[0]+offset[0]
        pixelY = (position[0][1]+position[3][1])/2+areaOffset[1]+offset[1]
        if tap:
            driver.tap(pixelX, pixelY, timeout=timeout)
        points = np.array(position, dtype=np.int32)
        cv2.polylines(img, [points], isClosed=True, color=(0, 0, 255), thickness=1)
        write_image(os.path.join('ocr_log',successLine.string,f'{time.time()}.png'),img)
        loopTime = 0
        return (pixelX, pixelY, True,successLine.string)
    if loop:
        if tapDirection:
            driver.tap(timeout=1, direction=tapDirection)
        if swipeDirection:
            driver.swipe(timeout=1, direction=swipeDirection)
        time.sleep(3)
        return findString(target, like, loop, tap, offset, timeout, tapDirection, swipeDirection)
    else:
        loopTime = 0
        return (None, None, False,None)

def getAllText():
    return [line.string for line in getFilteredResult(driver.getScreenshotForCv2())]
